package org.romzzz.gwtclassifieds.server.service;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.romzzz.gwtclassifieds.client.data.CategoryBean;
import org.romzzz.gwtclassifieds.client.data.ClassifiedBean;
import org.romzzz.gwtclassifieds.client.exception.AuthenticationException;
import org.romzzz.gwtclassifieds.client.exception.RpcException;
import org.romzzz.gwtclassifieds.client.service.ClassifiedService;
import org.romzzz.gwtclassifieds.server.data.FeedbackMessage;

import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class ClassifiedServiceImpl extends RemoteServiceServlet implements ClassifiedService {
	
	public Boolean enableAdminMode() throws AuthenticationException {
		try {
			return Boolean.valueOf(UserServiceFactory.getUserService().isUserAdmin());
		} catch (IllegalStateException e) {
			throw new AuthenticationException(e.getLocalizedMessage());
		}
	}

	public List<CategoryBean> addCategory(CategoryBean category) throws RpcException {
		if (enableAdminMode().booleanValue()) {
			ClassifiedsStorage.getInstance().addCategory(category);
		}
		return getCategories();
	}
	
	public List<CategoryBean> getCategories() throws RpcException {
		return ClassifiedsStorage.getInstance().getCategories();
	}
	
	public List<CategoryBean> removeCategory(CategoryBean category) throws RpcException {
		ClassifiedsStorage.getInstance().removeCategory(category);
		return getCategories();
	}

	public List<ClassifiedBean> addClassified(ClassifiedBean classified, String password, List<CategoryBean> categories) throws RpcException {
		ClassifiedsStorage.getInstance().addClassified(classified, password);
		return getCategorizedClassifieds(categories);
	}

	public Long checkAcces(Long id, String password) throws RpcException, AuthenticationException {
		return ClassifiedsStorage.getInstance().checkAccess(id, password);
	}

	public List<ClassifiedBean> getAllClassifieds() throws RpcException {
		return ClassifiedsStorage.getInstance().getClassifieds();
	}

	public List<ClassifiedBean> getCategorizedClassifieds(List<CategoryBean> categories) throws RpcException {
		List<ClassifiedBean> categorizedClassifieds = new ArrayList<ClassifiedBean>();
		for (ClassifiedBean classified: ClassifiedsStorage.getInstance().getClassifieds()) {
			if (categories.contains(classified.getCategory())) {
				categorizedClassifieds.add(classified);
			}
		}
		return categorizedClassifieds;
	}

	public List<ClassifiedBean> removeClassified(Long id, String password, List<CategoryBean> categories) throws RpcException, AuthenticationException {
		Long token = checkAcces(id, password);
		ClassifiedsStorage.getInstance().removeClassified(id, token);
		return getCategorizedClassifieds(categories);
	}

	public List<ClassifiedBean> updateClassified(ClassifiedBean classified, Long token, List<CategoryBean> categories) throws RpcException, AuthenticationException {
		if (ClassifiedsStorage.getInstance().updateClassified(classified, token)) {
			return getCategorizedClassifieds(categories);
		} else {
			throw new RpcException("The classified could not be updated");
		}
	}
	
	public Boolean sendFeedback(String name, String message) throws RpcException {
		Long id = Long.valueOf(System.currentTimeMillis());
		ClassifiedsStorage.getInstance().sendFeedback(new FeedbackMessage(name, message, id, DateFormat.getDateTimeInstance().format(new Date(id))));
		return Boolean.TRUE;
	}
}
